/**
 * @file
 * Implements sprite subsystem
 */
 
#include "c_Engine.h"
#include <assert.h>
#include "c_Sprite.h"

/**
 * Initialises sprite subsysm
 * pre allocates a load of sprite objects.
 * runtime allocation of sprites will be pulled from this pool
 */
wiigi::e_Status wiigi::c_Engine::initSprites( void )
{
   wiigi::e_Status Status;
   Status = d_StatusUnkown;
   
   //Allocate storage for vector
   m_FreeSprites.clear();
   m_FreeSprites.reserve( d_NumberOfSprites );
      
   //Allocate storage for sprites
   c_Sprite* Sprites;
   Sprites = new c_Sprite[ d_NumberOfSprites ];
   if( 0 == Sprites )
   {
      printf( "initSprites(): Unable to allocate memory for Sprites\n");
      Status = d_StatusNoMemory;
      goto Exit;
   }
   
   //Add sprits to vector
   c_Sprite* Sprite;
   Sprite = Sprites;
   for( u32 Idx = 0; Idx < d_NumberOfSprites; Idx++ )
   {
      m_FreeSprites.push_back( Sprite );
      Sprite++;
   }
   
   Status = d_StatusOK;
   
Exit:
   if( d_StatusOK != Status )
   {
      if( 0 != Sprites )
      {
         delete Sprites;
         Sprites = 0;
      }
   }
      
   assert( d_StatusUnkown != Status );
   return Status;
}


/**
 * Creates a sprite that covers whole texture
 *
 * @param Texture Source texture for sprite
 * @retval Sprite object or 0
 */
wiigi::c_Sprite* wiigi::c_Engine::createSprite( 
   c_Texture* Texture
)
{
   assert( 0 != Texture );
   
   c_Sprite* Sprite;
   Sprite = m_FreeSprites.back();
   m_FreeSprites.pop_back();
   assert( 0 != Sprite );
   if( 0 != Sprite )
   {  
      e_Status Status;
      Status = Sprite->init( Texture );
      if( d_StatusOK != Status )
      {
         delete Sprite;
         Sprite = 0;
      }
   }

   return Sprite;
}

/**
 * Creates a sprite that covers a selected part of the texture
 *
 * @param Texture   Source texture for sprite
 * @param FrameSize Rectangle descring region of src texture to use
 * @retval Sprite object or 0
 */
wiigi::c_Sprite* wiigi::c_Engine::createSprite( 
   c_Texture* Texture,
   c_u32Rect& FrameSize
   )
{
   assert( 0 != Texture );
   
   c_Sprite* Sprite;
   Sprite = m_FreeSprites.back();
   m_FreeSprites.pop_back();
   assert( 0 != Sprite );
   if( 0 != Sprite )
   {  
      e_Status Status;
      Status = Sprite->init( Texture, FrameSize );
      if( d_StatusOK != Status )
      {
         delete Sprite;
         Sprite = 0;
      }
   }

   return Sprite;
}

/**
 * Creates a sprite that has multiple frames
 *
 * @param Texture   Source texture for sprite
 * @param FrameSize Rectangle descring region of src texture to use
 * @param FrameCnt  Numnber of frames to create
 * @retval Sprite object or 0
 */
wiigi::c_Sprite* wiigi::c_Engine::createSprite( 
   c_Texture* Texture,
   c_u32Rect& FrameSize,
   u32        FrameCnt
   )
{
   assert( 0 != Texture );
   
   c_Sprite* Sprite;
   Sprite = m_FreeSprites.back();
   m_FreeSprites.pop_back();
   assert( 0 != Sprite );
   if( 0 != Sprite )
   {  
      e_Status Status;
      Status = Sprite->init( Texture, FrameSize, FrameCnt );
      if( d_StatusOK != Status )
      {
         delete Sprite;
         Sprite = 0;
      }
   }

   return Sprite;
}
